package com.atguigu.study.bootredis.controller;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author jiangta
 * @version 1.0
 * @date 2020/12/2 4:27 下午
 */
@RestController
public class GoodController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Value("${server.port}")
    private String serverPort;

    public static final String REDIS_LOCK_KEY = "lockhhf";

    @Autowired
    private Redisson redisson;

    @GetMapping("/buy_goods")
    public String buy_Goods() {
        String value = UUID.randomUUID().toString() + Thread.currentThread().getName();

//        RLock lock = redisson.getLock(REDIS_LOCK_KEY);
//        lock.lock();
        try {
            Boolean lockFlag = stringRedisTemplate.opsForValue().setIfAbsent(REDIS_LOCK_KEY, value,10, TimeUnit.SECONDS);//setnx
            //stringRedisTemplate.expire(REDIS_LOCK_KEY,10L, TimeUnit.SECONDS);
            if (!lockFlag) {
                System.out.println("抢锁失败， ┭┮ ﹏ ┭┮" + serverPort);
                return "抢锁失败， ┭┮ ﹏ ┭┮";
            }


            String result = stringRedisTemplate.opsForValue().get("goods:001");
            int goodsNumber = result == null ? 0 : Integer.parseInt(result);
            if (goodsNumber > 0) {
                int realNumber = goodsNumber - 1;
                stringRedisTemplate.opsForValue().set("goods:001", realNumber + "");
                //stringRedisTemplate.delete(REDIS_LOCK_KEY);// 释放锁
                System.out.println(" 你已经成功秒杀商品，此时还剩余： " + realNumber + " 件 " + " \t  服务器端口 : " + serverPort);
                return " 你已经成功秒杀商品，此时还剩余： " + realNumber + " 件 " + " \t  服务器端口 : " + serverPort;
            } else {
                System.out.println(" 商品已经售罄 / 活动结束 / 调用超时，欢迎下次光临 " + " \t  服务器端口 : " + serverPort);
            }
        } finally {
//            if(value.equals(stringRedisTemplate.opsForValue().get(REDIS_LOCK_KEY))) {
//                stringRedisTemplate.delete(REDIS_LOCK_KEY);// 释放锁
//            }
            // 读取 /resources/lua/compareAndSet.lua 脚本 。注意，需要引入下 commons-io 依赖。
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            // 创建 RedisScript 对象
            RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
            // 执行 LUA 脚本
            Long result = stringRedisTemplate.execute(redisScript, Collections.singletonList(REDIS_LOCK_KEY), value);
            if(result ==1) {
                System. out .println("------del REDIS_LOCK_KEY success");
            } else {
                System. out .println("------del REDIS_LOCK_KEY error");
            }
            //lock.unlock();
        }
        return " 商品已经售罄 / 活动结束 / 调用超时，欢迎下次光临 " + " \t  服务器端口 : " + serverPort;

    }

    @RequestMapping("testReentrant")
    public void ReentrantLock() {
        RLock lock = redisson.getLock("fibonacci");
        lock.lock();
        try {
//            int result = fibonacci(10);
//            System.out.println(result);
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

//    int fibonacci(int n) {
//        RLock lock = redisson.getLock("fibonacci");
//        try {
//            if (n <= 1) return n;
//            else
//                return fibonacci(n - 1) + fibonacci(n - 2);
//        } finally {
//            lock.unlock();
//        }
//    }
}
